#ifndef IMU9DOFDRIVER_H_
#define IMU9DOFDRIVER_H_

/************************************************************************************
*	Copyright Paxs Electronics 2012													*
*   All Rights Reserved																*
*   The Copyright symbol does not also indicate public availability or publication.	*
* 																					*
* 								PAXS ELECTRONICS									*
* 																					*
* - Driver:   			9DOF Sensor Stick Driver									*
* 																					*
* - Compiler:           Code Composer Studio (Licensed)								*
* - Supported devices:  All Stellaris Family Cortex-M3.								*
* - AppNote:																		*
*																					*
* 	Created by: 		Juan Francisco Gomez Ruiz									*
*   Date Created: 		10 - Dec - 2011												*
*   Contac				pacoduz@gmail.com											*
* 																					*
* 	Description: 		Full Read and configuration of the 9DOF sensor Stick, 		*
* 						Controlled by a Finite State Machine.						*
*   Device supported and tested: - LM3S5749 - LM3S3748 -							*
* 																				2012*
*************************************************************************************

*************************************************************************************
* 	Revision History:
*
*   Date          CP#           Author
*   MM-DD-YY      XXXXX:1       Initials   Description of change
*   -----------   -----------   --------   ------------------------------------
*    12-10-11      	1.0             JFGR	Initial version. Non a State Machine controlled
* 	 12-15-11		2.0				JFGR	Second Version.	Include State Machine controller 
*    12-17-13		2.0.1			JFGR	Second Version. Full Support, 3 sensors.

*************************************************************************************
* 	File/
*  	9 Degrees of Freedom Sensor Stick (9DOF) Driver 
*  	"Hardware abstraction Layer - First level".
*  	At 50Mhz  clock frequency, this Driver gets Accelerometer 
*  	and Gyroscope 3 Axis in 100us and 224 State Machine calls. 
*  	It takes 14 State Machine efective calls to get 3 axis data 
*  	from one Sensor. To read Accelerometer and Gyroscope 
*  	it takes 28 (12.5%) state machine efective calls 
*  	of 224 reported above. 
*  	So, it takes 12.5 us to Read Accelerometer and Gyroscope.
* 
*	New Version - Updates - "Read all 3 sensors"
* 	*Note: Stellaris at 50Mhz
* 	- Sample Average at 64 samples it takes 1.050mS - (950hz). to report new Data.
* 	- Sample Average at 32 samples it takes 960uS - (1042 hz). to report new Data.
* 	- Sample Average at 16 samples it takes 909uS - (1100 hz). to report new Data.
* 	- Sample Average at  8 samples it takes 892uS - (1120 hz). to report new Data.
* 	- Sample Average at  4 samples it takes 876uS - (1142 hz). to report new Data.
* 	- Sample Average at  2 samples it takes 873uS - (1147 hz). to report new Data.
* 	- Sample Average at  1 samples it takes 868uS - (1152 hz). to report new Data.
* 
*  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 
*  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 
*  OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 
*  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 
*  HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,  
*  WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 
*  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
*  DEALINGS IN THE SOFTWARE.
* 
*/

	#include "lm3s5749.h"
	#include "inc/hw_types.h"
	#include "driverlib/sysctl.h"
	#include "inc/hw_i2c.h"
	#include "driverlib/i2c.h"
	#include "inc/hw_memmap.h"
	#include "driverlib/gpio.h"
	
/******************************************************************************
*   						MACRO DEFINITIONS
******************************************************************************/
	//////////////////////////////
	//	 	I2C MODULE			//		
	//////////////////////////////
	#define I2C0   			0
	#define I2C1			1
	#define I2C_MODULE		(I2C0)		// Here is the Port that will handle the 9DOF IMU.
	#define I2C_400K		4
	#define I2C_100K		1
	
	//////////////////////////////////////////////
	//		SENSOR SAMPLES AVERAGE ORDER		//
	//////////////////////////////////////////////
	// Table:	
	//			Samples 64	-	Divisor 6
	//			Samples	32	-	Divisor	5
	//			Samples 16	-	Divisor	4
	//			Samples	8	-	Divisor	3
	//			Samples	4	-	Divisor	2
	//			Samples 2	-	Divisor	1
	//			Samples	1	-	Divisor 0
	#define SAMPLE_NUMBER	 16			// Number of Samples "Reads" of each single Axis and sensor
	#define DIVISOR			 4			// Instead make a Arithmetic Division, make a Division by shifting bits 
	
	//////////////////////////////////////////////////
	//	ACCELEROMETER REGISTERS ADDRESS & VALUES	//
	//////////////////////////////////////////////////
	#define	ACCELEROMETER_ADDRESS	0x53	//7-bit I2C address
	#define	POWER_CTL_R				0x2D
	#define BW_RATE_R				0x2C
	#define DATA_FORMAT_R			0x31
	#define TWO_G					0x00
	#define FOUR_G					0x01
	#define EIGHT_G					0x02
	#define MAX_G					0x03
	#define FULL_RES				0x08
	#define MEASURE_MODE			0x08
	#define JUSTIFY					0x04
	#define BANDWIDTH_1600			0x0F	//Rates in Hz
	#define	BANDWIDTH_800			0x0E
	#define BANDWIDTH_400			0x0D
	
	/*
	 *  Accelerometer SetUp
	 */	
	#define ACCELEROMETER_OUTPUT_RATE  	(BANDWIDTH_800)
	#define ACCELEROMETER_DATA_FORMAT	((TWO_G | FULL_RES))
	
	
	//////////////////////////////////////////////
	//	GYROSCOPE REGISTERS ADDRESS & VALUES	//
	//////////////////////////////////////////////
	#define GYROSCOPE_ADDRESS		0x68	//7-bit I2C address
	#define PWR_MGM_R				0x3E	//Power Managment register
	#define SMPLTR_DIV_R			0x15	//register
	#define DLPFS_FS_R				0x16	//register
	#define INT_CFG_R				0x17	//register
	#define RANGE_2000				0x18	//value
	#define	INT_SAMPLE_8K			0x00	//8khz internal sample and low-pass filter at 256hz
	#define INT_SAMPLE_1K			0x01	//8khz internal sample and low-pass filter at 188hz
	#define INT_SAMPLE_1K2			0x01	//8khz internal sample and low-pass filter at 98hz
	#define GYRO_RATE_8K			0x00	//value
	#define GYRO_RATE_4K			0x01	//
	#define GYRO_RATE_2K			0x03	//
	#define GYRO_RATE_1K			0x07	//
	#define GYRO_RESET				0x80	//Value to reset device and internal
	
	/*
	 *  Gyroscope SetUp
	 */	
	#define GYROSCOPE_FREQUENCY_DIVIDER	(0)	//From 0 to 256 
	#define GYROSCOPE_RATE_AND_SCALE  	((INT_SAMPLE_8K|RANGE_2000))
	
	//////////////////////////////////////////////
	//	MAGNETOMETER REGISTERS ADDRESS & VALUES	//
	//////////////////////////////////////////////
	#define MAGNETOMETER_ADDRESS	0x1E	//7-bit I2C address
	#define CONFIG_REG_A			0x00
	#define CONFIG_REG_B			0x01
	#define MODE_REGISTER			0x02
	#define STATUS_REGISTER			0x09
	#define OUTPUT_RATE_15			0x10	//OutPut Rates have Normal Operation
	#define OUTPUT_RATE_30			0x14
	#define OUTPUT_RATE_75			0x18
	#define MAG_GAIN_1_3			0x20
	#define MAG_GAIN_1_9			0x40
	#define MAG_GAIN_2_5			0x60
	#define MAG_GAIN_4_0			0x80
	#define CONTINUOUS				0x00
	#define SINGLE		  			0x01
	
	//To get the Magnetic Declination at your current or desire location
	//Visit: http://magnetic-declination.com/
	//then to get the Magnetic declination in MilliRadians
	//enter it in Wolfram Alpha:  http://www.wolframalpha.com/input/?i=%284%C2%B0+21%27%29+in+radians
	#define MAGN_DECLINATION		-0.1198				//Radians -  119.8 MilliRadians - 0.1198 Radians
														//Location: Guadalajara MEXICO. 
	/*
	 *  Magnetometer SetUp
	 */										
	#define MAGNETOMETER_OUTPUT_RATE				(OUTPUT_RATE_75)	//OutPut rate in HZ
	#define MAGNETOMETER_GAIN		(MAG_GAIN_1_3)		//Magnetometer Gain
	#define OPERATION_MODE			(CONTINUOUS)		//Operation mode
	#if     MAGNETOMETER_GAIN == MAG_GAIN_1_3			//Section to get Magne
		#define MAGNETOMETER_SENSITIVITY	1090
	#endif
	#if     MAGNETOMETER_GAIN == MAG_GAIN_1_9
		#define MAGNETOMETER_SENSITIVITY	820
	#endif
	#if     MAGNETOMETER_GAIN == MAG_GAIN_2_5
		#define MAGNETOMETER_SENSITIVITY	660
	#endif
	#if     MAGNETOMETER_GAIN == MAG_GAIN_4_0
		#define MAGNETOMETER_SENSITIVITY	440
	#endif
	
	typedef struct						//Structure to handle State Machin, that controls:
	{									// Reading and Writting of IMU Sensors.			 
		unsigned char ActualState;
		unsigned char NextState;
	}SM;
	
/******************************************************************************
*   						EXTERNAL VARIABLES
******************************************************************************/
			//	 AS Imu9DOFDriver OUTPUTs		//
	//////////////////////////////////////////////////////
	extern volatile short XAxisAcceleration,YAxisAcceleration,ZAxisAcceleration;
	extern volatile short XAxisAngularRate,YAxisAngularRate,ZAxisAngularRate;
	extern volatile short XAxisMagnetic,YAxisMagnetic,ZAxisMagnetic;
	//User should take care of this Flag in the Application
	//**Note: not critical for the Driver
	extern unsigned char  NewData;							
	
/******************************************************************************
*   					GLOBAL FUNCTION PROTOTYPES
******************************************************************************/
	void Vfn9DOFDriverInitialization (void);
	void Vfn9DOFDriver (void);
	void VfnReset9DOFDriver (void);
	void VfnWatchDog9DOFDriver (void);
	
#endif /*9DOFDRIVER_H_*/
